Dining Philosphers Problem (Concurrency Problem)

4 philosophers dine together at the same table. Each philosopher has their own place at the table. There is a fork between each plate. The dish served is a kind of spaghetti which has to be eaten with two forks. Each philosopher can only alternately think and eat. Moreover, a philosopher can only eat their spaghetti when they have both a left and right fork. Thus 2 forks will only be available when their 2 nearest neighbors are thinking, not eating. After an individual philosopher finishes eating, they will put down both forks.
              P0           // P=Philospher

          f0       f1      // f=fork

      P3              P1   // Philopsher[i] will pick up fork[i], fork[i+1]

          f3       f2

              P2

Steps:
1. Create 4 forks. vec[Arc<Mutex>]
2. Create 4 Philosophers (ie 4 Philospher structs in for loop)
3. Philopsher[i] gets fork[i], fork[i+1]
4. Write eat() function, which uses Arc

use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

struct Fork;

struct Philosopher {
    name: String,
    left_fork: Arc>,
    right_fork: Arc>,
}

impl Philosopher {
    fn eat(&self) {
        println!("{} is trying to eat", &self.name);
        let _left = self.left_fork.lock().unwrap();
        let _right = self.right_fork.lock().unwrap();

        println!("{} is eating...", &self.name);
        thread::sleep(Duration::from_millis(10));
    }
}

static PHILOSOPHERS: &[&str] =
    &["Ph1", "Ph2", "Ph3", "Ph4"];

fn main() {
    let mut handles = vec![]; // Store thread handles
    let mut forks = vec![];
    for _ in 0..PHILOSOPHERS.len() {
        forks.push(Arc::new(Mutex::new(Fork)));
    }

    for i in 0..PHILOSOPHERS.len() {
        let mut left_fork = Arc::clone(&forks[i]);
        let mut right_fork = Arc::clone(&forks[(i + 1) % forks.len()]);

        // To avoid a deadlock, we have to break the symmetry
        // somewhere. This will swap the forks without deinitializing
        // either of them.
        if i == forks.len() - 1 {
            std::mem::swap(&mut left_fork, &mut right_fork);
        }

        // Philospher=i gets ready
        let philosopher = Philosopher {
            name: PHILOSOPHERS[i].to_string(),
            left_fork,
            right_fork,
        };

        let handle = thread::spawn(move || {
            for _ in 0..10 {
                philosopher.eat();
            }
        });
        handles.push(handle); // Store the handle
    }
    for handle in handles {
        handle.join().unwrap();
    }
}

n Producer n Consumer